package ktvutil

import (
	"bytes"
	"encoding/binary"
	//"log"
	"os"
	"path/filepath"
	//"syscall"
	"time"
)

var (
	mapSongName      map[uint32]string
	IsSongdataLoaded bool
	LastModefyTime   int64
	LastCheckTime    int64

	// 下载歌曲统计
	downloadSongCount uint64
)

// 歌曲资料(不包含歌曲名称)
type KtvSongData struct {
	SongNum    uint32 // 4 BYTES
	NameStart  uint32 // 开始位置
	NameLength uint32 // 长度 bytes

	Pinyin    [10]uint16 // 20 BYTES
	SongIndex uint32     // avi的idx

	// 20 + 16 + 20
	SingerNum     [4]uint16 // 歌星编号
	Price         uint16    // 价格
	IsMtv         byte      // 是否MTV
	Lang          byte      // 语言编号
	Category      byte      // 分类编号
	WordCount     byte      // 歌曲名称字数
	Accompaniment byte      // 伴唱音轨
	Volume        byte      //音量
	Disk          byte      // 磁盘位置
	FileType      byte      // 文件类型
	Reserved      [2]byte   // 保留字段

}

// 歌曲资料
func (sd *KtvSongData) GetStructSize() uint32 {
	return 56
}

func init() {
	IsSongdataLoaded = false
	mapSongName = make(map[uint32]string)
}

func KtvGetSongNameByNum(SongNum uint32) string {

	// 获取指定编号以上的歌曲资料列表
	strSongdataPath := filepath.Join("SYSTEM", "SONGDATA.DAT") // 歌曲数据路径

	nowTime := time.Now().Unix()

	if nowTime > (LastCheckTime + 10*60) {
		nowModifyTime := GetModifyDate(strSongdataPath)
		LastCheckTime = nowTime

		if LastModefyTime != nowModifyTime {
			IsSongdataLoaded = false
			LastModefyTime = nowModifyTime
		}
	}

	if IsSongdataLoaded != true {
		ok := LoadSongName(strSongdataPath)
		IsSongdataLoaded = ok
	}

	val, ok := mapSongName[SongNum]
	if ok {
		return val
	}

	return ""
}

func LoadSongName(strFilePath string) bool {
	f, err := os.Open(strFilePath)
	if err != nil {
		return false
	}

	defer f.Close()

	fi, err := f.Stat()
	if fi.Size() <= 0 {
		return false
	}

	//读取文件
	buf := make([]byte, fi.Size())

	f.Read(buf)
	rd := bytes.NewReader(buf)

	//分析文件，copyright
	var copyright DatCopyright
	binary.Read(rd, binary.LittleEndian, &copyright)

	if copyright.IsShiyou() != true {
		return false
	}

	// 添加路径到map
	var i uint32
	for i = 0; i < copyright.RecordCount; i++ {
		var songdata KtvSongData

		recordOffset := copyright.GetStructSize() + songdata.GetStructSize()*i

		if recordOffset >= uint32(fi.Size()) {
			break
		}

		rd.Seek(int64(recordOffset), 0)
		binary.Read(rd, binary.LittleEndian, &songdata)

		if songdata.NameStart+songdata.NameLength >= uint32(fi.Size()) {
			continue
		}

		songname := []uint16{}
		rd.Seek(int64(songdata.NameStart), 0)

		var j uint32
		for j = 0; j < (songdata.NameLength / 2); j++ {
			var ch uint16
			binary.Read(rd, binary.LittleEndian, &ch)
			if ch == 0 {
				break
			}

			songname = append(songname, ch)
		} //end for j = 0; j < songdata.NameLength/2; j++

		name := UTF16ToString(songname)
		//log.Printf("SongNum = %d,  SongName = %s", songdata.SongNum, name)

		mapSongName[songdata.SongNum] = name

	} //end for i = 0; i < copyright.RecordCount; i++

	return true
}

func GetModifyDate(strFilePath string) int64 {
	f, err := os.Open(strFilePath)
	if err != nil {
		return 0
	}

	defer f.Close()

	fi, err := f.Stat()

	return fi.ModTime().Unix()
}

func IncDonwloadSongCount() {
	downloadSongCount++
}

func GetDownloadSongCount() uint64 {
	return downloadSongCount
}
